package pr1.cromosoma;


public class CromosomaF1 extends Cromosoma<Double> {

	private static final double XMIN = 0;
	private static final double XMAX = 32;
    private final int longX;

	private CromosomaF1(int longX) {
		super(longX);
        this.longX = longX;
		setAptitud(evalua());
	}

    @Override
    public CromosomaF1 clone() {
        CromosomaF1 clon = new CromosomaF1(longX);
        clon.copia(this);
        return clon;
    }

    public void copia(CromosomaF1 otro) {
        assert(this.longX == otro.longX);
        super.copia(otro);
    }

	@Override
	public final double evalua() {
        final double x = getX();
        double cnt = 20 + Math.E;
        double s1 = -20 * Math.pow(Math.E, -0.2 * Math.abs(x));
		double s2 = -Math.pow(Math.E, Math.cos(2 * Math.PI * x));
        return cnt + s1 + s2;
	}

	public double getX() {
		return XMIN + (XMAX - XMIN) * bin2dec(0, longX)
				/ (Math.pow(2, longX) - 1);
	}

    @Override
    public Double getFenotipo() {
        return getX();
    }

    @Override
    public String toString() {
        return "CromosomaF1{" + getAptitud() + '}';
    }

	public static class Factory implements CromosomaFactory<Double> {

		double precision;
		int longCromosoma;

		public double getPrecision() {
			return precision;
		}

		public void setPrecision(double precision) {
			this.precision = precision;
			longCromosoma = (int) Math.ceil(Math.log(1 + (XMAX - XMIN)
					/ precision)
					/ Math.log(2));
		}

		public Cromosoma<Double> generaCromosoma() {
			return new CromosomaF1(longCromosoma);
		}
		
		public String toString() {
			return "Cromosoma 1";
		}
	}

}
